package tjs.study.mini.springbootstartsmini.boot;

import org.springframework.context.ApplicationContextException;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.web.context.support.GenericWebApplicationContext;
import tjs.study.mini.springbootstartsmini.boot.web.ServletContextInitializer;
import tjs.study.mini.springbootstartsmini.boot.web.TomcatServletWebServerFactory;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.Map;

public class AnnotationConfigServletWebServerApplicationContext extends GenericWebApplicationContext {

//    private final AnnotatedBeanDefinitionReader reader;
//
//    private final ClassPathBeanDefinitionScanner scanner;

    private TomcatServletWebServerFactory servletWebServerFactory = new TomcatServletWebServerFactory();

    public AnnotationConfigServletWebServerApplicationContext() {
//        this.reader = new AnnotatedBeanDefinitionReader(this);
//        this.scanner = new ClassPathBeanDefinitionScanner(this);
        // 无需new上面两个对象，关键在于registerAnnotationConfigProcessors 注册了几个关键的类
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this);
    }

    @Override
    protected void onRefresh() {
        super.onRefresh();
        try {
            servletWebServerFactory.createWebServer(getSelfInitializer());//创建并启动 tomact
        } catch (Throwable ex) {
            throw new ApplicationContextException("Unable to start web server", ex);
        }
    }

    private ServletContextInitializer getSelfInitializer() {
        //返回的是selfInitialize方法的引用，此时还未执行 相当于ServletWebServerApplicationContext间接实现了ServletContextInitializer接口
        //这样写可以更方便获取BeanFactory等
        return this::selfInitialize;
    }

    private void selfInitialize(ServletContext servletContext) throws ServletException {
        Map<String, ServletContextInitializer> stringServletContextInitializerMap = super.getBeansOfType(ServletContextInitializer.class, true, false);
        for (Map.Entry<String, ServletContextInitializer> initializerEntry : stringServletContextInitializerMap.entrySet()) {
            initializerEntry.getValue().onStartup(servletContext);
        }
    }

}